import { defineStore } from "pinia";
import { computed, reactive, toRaw, watch } from "vue";
import { getProjDetailByIdAPI } from "@/api/dataview/project";
import { useRoute } from "vue-router";
import type { ResType } from "@/api/types";
import { cloneDeep, isArray, isNumber, isString } from "lodash";
import { useDataViewHistoryStore } from "./dataviewHistory";
import { HistoryActionTypeEnum, type ChartEditStoreType, type EditCanvasConfigType, type EditCanvasType, type RecordChartType } from "./types";
import { SyncEnum } from "@/types";
import { globalThemeJson } from "@/views/dataview/setting/chartTheme";
import { componentInstall, getUUID, showMsg } from "@/utils";
import { fetchChartComponent, fetchConfigComponent } from "@/views/dataview/packages";
import type { CreateComponentGroupType, CreateComponentType } from "@/views/dataview/packages/public/type";
import { PublicGroupConfigClass } from "@/views/dataview/packages/public/publicConfig";
import { requestInterval, requestIntervalUnit } from "@/views/dataview/setting/designSetting";
import type { HistoryItemType } from "./types/dataviewHistory";
import { HistoryStackEnum, HistoryStackItemEnum, HistoryTargetTypeEnum } from "./types/dataviewHistory";
// 大屏数据
export const useDataViewStore = defineStore("dataView", () => {
    const route = useRoute()
    const dataviewHistoryStore = useDataViewHistoryStore()

    const dataviewState = reactive<ChartEditStoreType>({
        // 后端Content字段包含componentList，editCanvasConfig
        componentList: [], //组件列表
        editCanvasConfig: {
            // 项目名称
            projectName: undefined,
            // 默认宽度
            width: 1920,
            // 默认高度
            height: 1080,
            // 启用滤镜
            filterShow: false,
            // 色相
            hueRotate: 0,
            // 饱和度
            saturate: 1,
            // 对比度
            contrast: 1,
            // 亮度
            brightness: 1,
            // 透明度
            opacity: 1,
            // 变换（暂不更改）
            rotateZ: 0,
            rotateX: 0,
            rotateY: 0,
            skewX: 0,
            skewY: 0,
            // 混合模式
            blendMode: 'normal',
            // 默认背景色
            background: 'rgb(0, 0, 0)',
            backgroundImage: undefined,
            // 是否使用纯颜色
            selectColor: true,
            // chart 主题色
            chartThemeColor: 'dark',
            // 自定义颜色列表
            chartCustomThemeColorInfo: undefined,
            // 全局配置
            chartThemeSetting: globalThemeJson,
            // vChart 主题
            vChartThemeName: 'vScreenVolcanoBlue',
        },
        projDetail: {
            projectName: "",
            coverImg: "",
            remark: "",
            status: 1, // 1 启用 2 禁用
            isTemplate: 2, // 1 模板 2 非模板
            isPublish: 2, // 1 发布 2 未发布
        },
        // 目标图表
        targetChart: {
            hoverId: undefined,
            selectId: [] as any[]
        },
        // 画布属性
        editCanvas: {
            // 编辑区域 Dom
            editLayoutDom: null,
            editContentDom: null,
            // 偏移量
            offset: 20,
            // 系统控制缩放
            scale: 1,
            // 用户控制的缩放
            userScale: 1,
            // 锁定缩放
            lockScale: false,
            // 初始化
            isCreate: false,
            // 拖拽中
            isDrag: false,
            // 框选中
            isSelect: false,
            // 代码编辑中
            isCodeEdit: false,
            saveStatus: SyncEnum.PENDING
        },
        // 右键菜单
        rightMenuShow: false,
        // 鼠标定位
        mousePosition: {
            startX: 0,
            startY: 0,
            x: 0,
            y: 0
        },
        requestGlobalConfig: {
            requestDataPond: [],
            requestOriginUrl: '',
            requestInterval: requestInterval,
            requestIntervalUnit: requestIntervalUnit,
            requestParams: {
                Body: {
                    'form-data': {},
                    'x-www-form-urlencoded': {},
                    json: '',
                    xml: ''
                },
                Header: {},
                Params: {}
            }
        },
        // 记录临时数据（复制等）
        recordChart: undefined,
    })


    const getEditCanvas = computed(() => {
        return dataviewState.editCanvas
    })
    const getEditCanvasConfig = computed(() => {
        return dataviewState.editCanvasConfig
    })

    const getTargetChart = computed(() => {
        return dataviewState.targetChart
    })

    const getComponentList = computed(() => {
        return dataviewState.componentList
    })

    const getRecordChart = computed(() => {
        return dataviewState.recordChart
    })

    const getRequestGlobalConfig = computed(()=>{
        return dataviewState.requestGlobalConfig
    })

    const init = async () => {
        const res = await getProjDetailByIdAPI({ id: route.params.id }) as ResType<any>
        const data = res.data.result
        dataviewState.projDetail.projectName = data.projectName
        dataviewState.projDetail.coverImg = data.coverImg
        dataviewState.projDetail.remark = data.remark
        dataviewState.projDetail.status = data.status
        dataviewState.projDetail.isTemplate = data.isTemplate
        dataviewState.projDetail.isPublish = data.isPublish
        const contentJson = JSON.parse(data.content)
        // 取存储的字段赋值
        dataviewState.componentList = contentJson.componentList ?? []
        dataviewState.editCanvasConfig = contentJson.editCanvasConfig ?? dataviewState.editCanvasConfig
        dataviewState.requestGlobalConfig = contentJson.requestGlobalConfig ?? dataviewState.requestGlobalConfig
        // 动态注册现有组件，防止刷新浏览器未注册情况
        dataviewState.componentList.forEach((comp: any) => {
            componentInstall(comp.chartConfig.chartKey, fetchChartComponent(comp.chartConfig))
            componentInstall(comp.chartConfig.conKey, fetchConfigComponent(comp.chartConfig))
        })
    }

    /**
     * 设置选中的图标用于激活样式
     * @param selectId 
     * @param push 插入id方式
     * @returns 
     */
    const setTargetSelectChart = (selectId?: any, push: boolean = false) => {
        if(dataviewState.targetChart.selectId.find(i=>i == selectId)) return
        if (!selectId) {
            dataviewState.targetChart.selectId = []
            return
        }
        if (push) {
            if (isArray(selectId)) {
                dataviewState.targetChart.selectId.push(...selectId)
                return
            }else{
                dataviewState.targetChart.selectId.push(selectId)
                return
            }
        } else {
            if (isString(selectId) || isNumber(selectId)) {
                dataviewState.targetChart.selectId = [selectId]
                return
            }
            if (isArray(selectId)) {
                dataviewState.targetChart.selectId = selectId
                return
            }
        }   
    }
    


    const setTargetHoverChart = (hoverId: any) => {
        dataviewState.targetChart.hoverId = hoverId
    }

    

    // 根据id查找下标位置
    const fetchTargetIndex = (id?: string | number) => {
        const targetId = id || (dataviewState.targetChart.selectId.length && dataviewState.targetChart.selectId[0]) || undefined
        if (!targetId) {
            return -1
        }
        const targetIndex = dataviewState.componentList.findIndex((item: any) => item.id === targetId)

        if (targetIndex !== -1) {
            // 单个组件的情况
            return targetIndex //找到了
        } else {
            // 分组情况
        }
        return -1 //没找到
    }

    const setMousePosition = (x?: number, y?: number, startX?: number, startY?: number) => {
        if (x) dataviewState.mousePosition.x = x
        if (y) dataviewState.mousePosition.y = y
        if (startX) dataviewState.mousePosition.startX = startX
        if (startY) dataviewState.mousePosition.startY = startY
    }
    const setEditCanvas = (key: any, value: any) => {
        // @ts-ignore
        dataviewState.editCanvas[key] = value
    }

    const setEditCanvasConfig = <T extends keyof EditCanvasConfigType,K extends EditCanvasConfigType[T]>(key:T,val:K)=>{
        dataviewState.editCanvasConfig[key] = val
    }

    // 移动组件
    const moveComponentList = (item: any[]) => {
        dataviewHistoryStore.createMoveHistory(item)
    }

    /**
     * 
     * @param componentInstance 
     * @param isHead 
     * @param isHistory 是否添加历史记录
     */
    const addComponnetList = (componentInstance: any, isHead = false, isHistory = false) => {
        if (Array.isArray(componentInstance)) {
            componentInstance.forEach((item: any) => {
                // 循环单独处理每个组件数据
                addComponnetList(item, isHead, isHistory)
            })
            return
        }
        // 记录历史操作
        if (isHistory) {
            dataviewHistoryStore.createAddHistory([componentInstance])
        }
        if (isHead) {
            // @ts-ignore
            dataviewState.componentList.unshift(componentInstance)
            return
        }
        // @ts-ignore
        dataviewState.componentList.push(componentInstance)
    }

    const updateComponentList = (index:number,chart:CreateComponentType | CreateComponentGroupType)=>{
        if(index > getComponentList.value.length && index < 1) return
        dataviewState.componentList[index] = chart
    }

    const idPreFormat = (ids?: any) => {
        const idArr: any[] = []
        if (!ids) {
            idArr.push(...getTargetChart.value.selectId)
            return idArr
        }
        if (Array.isArray(ids)) {
            idArr.push(...ids)
        } else {
            idArr.push(ids)
        }
        return idArr
    }

    const removeComponentList = (ids?: any, isHistory = true) => {
        const idArr = idPreFormat(ids) //确保id一定是数组
        // 记录删除历史操作
        const history: Array<CreateComponentType | CreateComponentGroupType> = []
        if (idArr.length == 0) return
        idArr.forEach((id: any) => {
            const index = fetchTargetIndex(id)
            if (index != -1) {
                history.push(getComponentList.value[index]) //当前图表插入历史记录
                dataviewState.componentList.splice(index, 1) //删除数据
            }
        })
        if (isHistory) {
            // 处理历史记录
            dataviewHistoryStore.createDeleteHistory(history)
        }
    }

    const setRecordChart = (data: RecordChartType | undefined) => {
        dataviewState.recordChart = cloneDeep(data)
    }


    const getSelectComponent = ()=>{
        const index = fetchTargetIndex()
        if(index != -1) {
            return getComponentList.value[index]
        }
    }

    // 获取针对 componentList 顺序排过序的 selectId
    const getSelectIdSortList = (ids:any[])=>{
        // 未选中并且没有ids传递
        if(getTargetChart.value.selectId.length == 0 && !ids) return[]
        const sortArr:any[]= []
        getComponentList.value.forEach((item:CreateComponentType|CreateComponentGroupType)=>{
            if(ids){
                ids.forEach((id)=>{
                    if(item.id == id){
                        sortArr.push(id)
                    }
                })
            }else{
                getTargetChart.value.selectId.forEach((id)=>{
                    if(item.id === id){
                        sortArr.push(id)
                    }
                })
            }
        })
        // 返回升序结果
        // return sortArr.sort((a,b)=>a-b)
        return sortArr
    }

    /**
     * 锁定
     * @param status 状态，处理锁定历史记录或解锁历史记录
     * @param isHistory 
     * @returns 
     */
    const lockFun = (status: boolean = true, isHistory: boolean = true) => {
        // 只能锁定单个组件
        if(getTargetChart.value.selectId.length > 1) return
        const index = fetchTargetIndex()
        if(index != -1){
            const chart = getComponentList.value[index]
            chart.status.lock = status //开启锁定
            if(isHistory){
                // 处理历史记录
            }
            updateComponentList(index,chart)
            if(status){
                // 锁定添加失焦效果
                setTargetSelectChart(undefined)
            }
        }
    }
    const unLockFun = (isHistory: boolean = true)=>{
        lockFun(false,isHistory)
    }
    // 复制
    const copy = (isCut = false) => {
        if (getTargetChart.value.selectId.length == 0) return
        const index = fetchTargetIndex()
        if (index != -1) {
            const chart = getComponentList.value[index]
            const copyData: RecordChartType = {
                charts: chart,
                type: isCut ? HistoryActionTypeEnum.CUT : HistoryActionTypeEnum.COPY
            }
            // 复制数据
            setRecordChart(copyData)
            showMsg(isCut ? "剪切成功" :"复制成功", 'success')
        }
    }
    // 剪切
    const cut = () => {
        copy(true)
    }
    // 粘贴
    const paste = (event: MouseEvent) => {
        const scale = dataviewState.editCanvas.scale
        const recordCharts = getRecordChart.value        
        if (!recordCharts) return
        const isCut = recordCharts.type === HistoryActionTypeEnum.CUT
        // 处理位置，id等属性修改
        const parseHandler = (item: CreateComponentType | CreateComponentGroupType) => {
            item = cloneDeep(item)
            item.id = getUUID()
        
            let curX = dataviewState.mousePosition.startX
            let curY = dataviewState.mousePosition.startY
            const distance = 50 //预留位置
            // 基于左上角检测
            curX = curX < -item.attr.w + distance ? -item.attr.w + distance : curX
            curY = curY < -item.attr.h + distance ? -item.attr.h + distance : curY

            // 基于右下角检测
            curX = curX > dataviewState.editCanvasConfig.width - distance ? dataviewState.editCanvasConfig.width - distance : curX
            curY = curY > dataviewState.editCanvasConfig.height - distance ? dataviewState.editCanvasConfig.height - distance : curY
            // 修改位置为当前鼠标位置
            item.attr.x = curX
            item.attr.y = curY

            if (item.isGroup) {
                item.groupList?.forEach(item=>{
                    item.id = getUUID()
                })
            }
            return item
        }
        const targetCharts = Array.isArray(recordCharts.charts) ? recordCharts.charts : [recordCharts.charts]
        targetCharts.forEach((item: CreateComponentType | CreateComponentGroupType) => {
            // 可能是一个组件或者分组
            addComponnetList(parseHandler(item), undefined, true)
            if (isCut) {
                // 删除旧数据
                setTargetSelectChart(item.id)
                removeComponentList(undefined, true)
            }
        })
        if (isCut) setRecordChart(undefined)
    }
    // 清空剪切板
    const closeClipboard = (data:RecordChartType | undefined) => {
        setRecordChart(data)
    }
    // 删除图表
    const deleteChart = () => {
        // 右击菜单可以激活图表，此时有selectid可以继续删除
        // if (getTargetChart.value.selectId.length == 0) return
        // const selectIds: any[] = [...getTargetChart.value.selectId]
        // selectIds.forEach((id: any) => {
        //     const index = fetchTargetIndex(id)
        //     if (index != -1) {
        //         dataviewState.componentList.splice(index, 1)
        //     }
        // })
        removeComponentList()
    }

    // 创建分组
    const setGroup = (id?:any,isHistory = true)=>{
        let selectIds = idPreFormat(id) || getTargetChart.value.selectId
        selectIds = getSelectIdSortList(selectIds)
        if(selectIds.length < 2) return // 分组至少需要两个图表
        const groupClass  = new PublicGroupConfigClass()
        const targetList:CreateComponentType[] = []
        const historyList: CreateComponentType[] = []

        // 处理完毕后的组合图表ids
        const newSelectIds:string[] = []
        // 如果是分组和单图表组合，则把分组的先解除
        selectIds.forEach((id)=>{
            const targetIndex = fetchTargetIndex(id)
            if(targetIndex != -1 && getComponentList.value[targetIndex].isGroup){
                setUnGroup(
                    [id],
                    (e:CreateComponentType[])=>{
                        e.forEach((e)=>{
                            // 解除分组，并重新将图表添加到组件列表中
                            addComponnetList(e)
                            newSelectIds.push(e.id)
                    }),
                    false
                })
            }else if(targetIndex != -1){
                newSelectIds.push(id)
            }
        })
        // 记录整体坐标
        const groupAttr = {
            l: 0,
            t: 0,
            r: 0,
            b: 0
        }
        newSelectIds.forEach((id,index)=>{
            // 选中的组合图表id需要从component中删除
            const item:CreateComponentType= dataviewState.componentList.splice(fetchTargetIndex(id),1)[0] //删除数据并取出删除的内容
            const {x,y,w,h} = item.attr
            // 设置分组的坐标，取所有最边上元素的的最大值组成组
            if(index == 0){
                groupAttr.l = x
                groupAttr.t = y
                groupAttr.r = x + w
                groupAttr.b = y + h
            }else{
                let {l,t,r,b} = groupAttr
                // 计算出左上角位置
                groupAttr.l = l > x ? x: l
                groupAttr.t = t > y ? y: t
                // 记录出右下角位置
                groupAttr.r = r < x + w ? x + w: r
                groupAttr.b = b < y + h ? y + h: b
            }
            targetList.push(item)
            historyList.push(toRaw(item))
        })
        // 处理历史记录
        if(isHistory){
            dataviewHistoryStore.createGroupHistory(historyList)
        }
        // 设置子组件位置,定位相对于当前分组计算
        targetList.forEach((item)=>{
            item.attr.x = item.attr.x - groupAttr.l
            item.attr.y = item.attr.y - groupAttr.t
            groupClass.groupList.push(item)
        })
        
        // 组件数据
        groupClass.attr.x = groupAttr.l
        groupClass.attr.y = groupAttr.t
        groupClass.attr.w = groupAttr.r - groupAttr.l
        groupClass.attr.h = groupAttr.b - groupAttr.t
        addComponnetList(groupClass)
        setTargetSelectChart(groupClass.id)
    }
    // 取消分组
    const setUnGroup = (ids?:any[],callBack?:(e:CreateComponentType[])=>void,isHistory = true)=>{
        const selectGroupIdArr = ids || getTargetChart.value.selectId
        if(selectGroupIdArr.length !== 1) return //有且只有一个
        const unGroup = (targetIndex:number)=>{
            const targetGroup:CreateComponentGroupType = getComponentList.value[targetIndex] as CreateComponentGroupType

            if(!targetGroup.isGroup) return

            if(isHistory){
                dataviewHistoryStore.createUnGroupHistory(cloneDeep([targetGroup]))
            }
            targetGroup.groupList.forEach((item:CreateComponentType)=>{
                // 重新计算每一个子组件的定位位置
                item.attr.x = item.attr.x + targetGroup.attr.x
                item.attr.y = item.attr.y + targetGroup.attr.y
                if(!callBack){
                    addComponnetList(item)
                }
            })
            setTargetSelectChart(targetGroup.id)
            // 删除分组
            removeComponentList(targetGroup.id,false)
            if(callBack){
                // 重新添加分组里面的图表到component中
                callBack(targetGroup.groupList)
            }
        }
        const targetIndex = fetchTargetIndex(selectGroupIdArr[0])
        if(targetIndex !== -1){
            unGroup(targetIndex)
        }
    }

    // 前进后退需要处理组件创建和销毁
    const setBack = ()=>{
        const targetData = dataviewHistoryStore.backAction()
        if(!targetData) return
        setBackAndSetForwardHandle(targetData)
    }

    const setForward  = ()=>{
        const targetData = dataviewHistoryStore.forwardAction()
        if(!targetData) return
        setBackAndSetForwardHandle(targetData,true)
    }

    const resetComponentPosition = (item: CreateComponentType | CreateComponentGroupType, isForward: boolean)=>{
        const index = fetchTargetIndex(item.id)
        if(index > -1){
            const instance = getComponentList.value[index]
            if(isForward){
                instance.attr = Object.assign(instance.attr,{
                    x:item.attr.x + item.attr.offsetX,
                    y:item.attr.y + item.attr.offsetY
                })
            }else{
                instance.attr = Object.assign(instance.attr,{
                    x:item.attr.x,
                    y:item.attr.y
                })
            }
        }
    }

    const setBackAndSetForwardHandle = (HistoryItem: HistoryItemType, isForward = false)=>{
        // 处理画布
        if(HistoryItem[HistoryStackItemEnum.TARGET_TYPE] === HistoryTargetTypeEnum.CANVAS){
            dataviewState.editCanvas = HistoryItem[HistoryStackItemEnum.HISTORY_DATA][0] as EditCanvasType
            return
        }
        setTargetSelectChart() //取消选中
        // 再次选中
        let historyData = HistoryItem[HistoryStackItemEnum.HISTORY_DATA] as CreateComponentType[] | CreateComponentGroupType[]
        if(isArray(historyData)){
            historyData.forEach((item:CreateComponentType | CreateComponentGroupType)=>{
                setTargetSelectChart(item.id,true)
            })
        }

        // 新增和删除
        const isAdd = HistoryItem[HistoryStackItemEnum.ACTION_TYPE] === HistoryActionTypeEnum.ADD
        const isDel = HistoryItem[HistoryStackItemEnum.ACTION_TYPE] === HistoryActionTypeEnum.DELETE
        if(isAdd || isDel){
            if((isAdd && isForward) || (isDel && !isForward)){
                historyData.forEach((item)=>{
                    addComponnetList(item)
                })
                return
            }
            historyData.forEach((item)=>{
                removeComponentList(item.id,false)
            })
            return
        }
        // 移动
        const isMove = HistoryItem[HistoryStackItemEnum.ACTION_TYPE] === HistoryActionTypeEnum.MOVE
        if(isMove){
            historyData.forEach(item=>{
                resetComponentPosition(item,isForward)
            })
            return
        }
        // 分组
        const isGroup = HistoryItem[HistoryStackItemEnum.ACTION_TYPE] === HistoryActionTypeEnum.GROUP
        const isUnGroup = HistoryItem[HistoryStackItemEnum.ACTION_TYPE] === HistoryActionTypeEnum.UN_GROUP
        if(isGroup || isUnGroup){
            if((isGroup && isForward) || (isUnGroup && !isForward)){
                const ids:any[] = []
                if(historyData.length > 1){
                    historyData.forEach(item=>{
                        ids.push(item.id)
                    })
                }else{
                    const group = historyData[0] as CreateComponentType
                    group.groupList?.forEach(item=>{
                        ids.unshift(item.id)
                    })
                }
                setGroup(ids,false)
                return
            }
            if(historyData.length > 1){
                setUnGroup([(historyData[0] as CreateComponentType).id],undefined,false)
            }else{
                setUnGroup([(historyData[0] as CreateComponentGroupType).groupList[0].id], undefined, false)
            }
            return
        }
        // 锁定
        const isLock = HistoryItem[HistoryStackItemEnum.ACTION_TYPE] === HistoryActionTypeEnum.LOCK
        const isUnLock = HistoryItem[HistoryStackItemEnum.ACTION_TYPE] === HistoryActionTypeEnum.UNLOCK
        if(isLock || isUnLock){
            if((isLock && isForward) || (isUnLock && !isForward)){
                historyData.forEach(item=>{
                    lockFun(item.status.lock,false)
                })
                return
            }
            historyData.forEach(item=>{
                unLockFun(false)
            })
            return
        }
    }


    watch(()=>dataviewState.componentList,()=>{
        console.log(dataviewState.componentList);
    },{deep:true})

    return {
        dataviewState,
        getEditCanvas,
        getEditCanvasConfig,
        getTargetChart,
        getComponentList,
        getRequestGlobalConfig,
        init,
        setTargetSelectChart,
        setTargetHoverChart,
        fetchTargetIndex,
        setMousePosition,
        setEditCanvas,
        setEditCanvasConfig,
        moveComponentList,
        addComponnetList,
        lockFun,
        copy,
        cut,
        paste,
        closeClipboard,
        deleteChart,
        unLockFun,
        getSelectComponent,
        setGroup,
        setUnGroup,
        setBack,
        setForward,
        setBackAndSetForwardHandle,
        resetComponentPosition
    }
})